#ifndef OPTICAL_FLOW_H_
#define OPTICAL_FLOW_H_

#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

/**
 * single level optical flow
 * @param [in] img1 the first image
 * @param [in] img2 the second image
 * @param [in] kp1 keypoints in img1
 * @param [in|out] kp2 keypoints in img2, if empty, use initial guess in kp1
 * @param [out] success true if a keypoint is tracked successfully
 * @param [in] inverse use inverse formulation?
 */
void OpticalFlowSingleLevel(const Mat &img1,
                            const Mat &img2,
                            const vector<KeyPoint> &kp1,
                            vector<KeyPoint> &kp2,
                            vector<bool> &success,
                            bool inverse = false,
                            bool has_initial_guess = false);

/**
 * multi level optical flow, scale of pyramid is set to 2 by default
 * the image pyramid will be create inside the function
 * @param [in] img1 the first pyramid
 * @param [in] img2 the second pyramid
 * @param [in] kp1 keypoints in img1
 * @param [out] kp2 keypoints in img2
 * @param [out] success true if a keypoint is tracked successfully
 * @param [in] inverse set true to enable inverse formulation
 */
void OpticalFlowMultiLevel(const Mat &img1,
                           const Mat &img2,
                           const vector<KeyPoint> &kp1,
                           vector<KeyPoint> &kp2,
                           vector<bool> &success,
                           bool inverse = false);

#endif
